package org.spring.springboot.controller;

import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spring.springboot.response.BaseResponse;
import org.spring.springboot.response.Constant;
import org.spring.springboot.response.ImageReturnRes;
import org.spring.springboot.response.OcrReturnRes;
import org.spring.springboot.utility.JnaImports;
import org.spring.springboot.utility.Utils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Time: 2017/9/19 上午9:54.
 * Created: vista @ ebudaowei.cn
 */
@RestController
public class HomeController {

    @Value("${face-cfg.det-model}")
    private String det_model;

    @Value("${face-cfg.landmark-model}")
    private String landmark_model;

    @Value("${face-cfg.model-pic}")
    private String model_pic;

    @Value("${face-cfg.upload-path}")
    private String pic_path;

    @Value("${face-cfg.ocr-upload-path}")
    private String ocr_upload_path;

    @Value("${face-cfg.ocr-nn-model}")
    private String nn_model_path;

    @RequestMapping(value = "/")
    public String hello()
    {
        JnaImports.CLibrary2.INSTANCE.hello();
        JnaImports.CLibraryOcr.INSTANCE.hello();
        return "hello,welcome to springboot-face & ocr";
    }

    private final Logger logger = LogManager.getLogger(this.getClass());

    private boolean bInit = false;

    private boolean bInitOcr = false;

    @RequestMapping(value = "/init")
    public ResponseEntity<BaseResponse> init()
    {
        BaseResponse baseResponse = new BaseResponse();
//        String out_path = Paths.get(pic_path,"1.jpg").toString();
        int ret = JnaImports.CLibrary2.INSTANCE.init(landmark_model,det_model);
        if(ret == -1){
            baseResponse.setMessage("init face failed");
            return new ResponseEntity<>(baseResponse, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        bInit = true;

        baseResponse.setStatus(Constant.successStr);
        baseResponse.setMessage("init success");
        return new ResponseEntity<>(baseResponse, HttpStatus.OK);
    }

    @RequestMapping(value = "/init_ocr")
    public ResponseEntity<BaseResponse> init_ocr()
    {
        BaseResponse baseResponse = new BaseResponse();
//        String out_path = Paths.get(pic_path,"1.jpg").toString();
        int ret = JnaImports.CLibraryOcr.INSTANCE.init(nn_model_path,ocr_upload_path);
        if(ret == -1){
            baseResponse.setMessage("init ocr failed");
            return new ResponseEntity<>(baseResponse, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        bInitOcr = true;

        baseResponse.setStatus(Constant.successStr);
        baseResponse.setMessage("init success");
        return new ResponseEntity<>(baseResponse, HttpStatus.OK);
    }


    @RequestMapping(value = "/run")
    public ResponseEntity<ImageReturnRes> run(/*HttpServletResponse response, HttpServletRequest request,*/
        @RequestParam(value = "file") MultipartFile file,
        @RequestParam(value = "model", required = false) MultipartFile modelfile,
        @RequestParam(value = "flag", required = false, defaultValue = "0") int flag
    )
    {
        ImageReturnRes imageReturnRes = new ImageReturnRes();

        if(!bInit)
        {
            imageReturnRes.setMessage("not init yet");
            return new ResponseEntity<>(imageReturnRes, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        SimpleDateFormat simpleDateFormat  = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
        Date date = new Date();
        String dataStr = simpleDateFormat.format(date);

        String out_path = Paths.get(pic_path,dataStr+"-1.jpg").toString();
        String photo_path = Paths.get(pic_path,dataStr+"-2.jpg").toString();
        String model_path = Paths.get(pic_path,dataStr+"-3.jpg").toString();

        JnaImports.CLibrary2.INSTANCE.set_outpath(out_path);

        boolean bd1 = Utils.downloadRequestFile(file,photo_path,imageReturnRes);

        if(!bd1)
        {
            return new ResponseEntity<>(imageReturnRes, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        int ret = -1;

        if(modelfile!=null){

            boolean bd2 = Utils.downloadRequestFile(modelfile,model_path,imageReturnRes);

            if(!bd2)
            {
                return new ResponseEntity<>(imageReturnRes, HttpStatus.INTERNAL_SERVER_ERROR);
            }

            if(flag == 0)
                ret = JnaImports.CLibrary2.INSTANCE.swap_head(photo_path,model_path);
            else
                ret = JnaImports.CLibrary2.INSTANCE.swap_face(photo_path,model_path);
        }else {
            if(flag == 0)
                ret = JnaImports.CLibrary2.INSTANCE.swap_head(photo_path,model_pic);
            else
                ret = JnaImports.CLibrary2.INSTANCE.swap_face(photo_path,model_pic);
        }

        if(ret != 0){
            imageReturnRes.setMessage("change head failed");
            return new ResponseEntity<>(imageReturnRes, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        imageReturnRes.setPath("/"+dataStr+"-1.jpg");
        imageReturnRes.setMessage("ok");
        imageReturnRes.setStatus(Constant.successStr);
        return new ResponseEntity<>(imageReturnRes, HttpStatus.OK);

    }

    @RequestMapping(value = "/ocr")
    public ResponseEntity<OcrReturnRes> ocr(
                                              @RequestParam(value = "file") MultipartFile file
    )
    {
        OcrReturnRes ocrReturnRes = new OcrReturnRes();

        if(!bInitOcr)
        {
            ocrReturnRes.setMessage("not init yet");
            return new ResponseEntity<>(ocrReturnRes, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        SimpleDateFormat simpleDateFormat  = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
        Date date = new Date();
        String dataStr = simpleDateFormat.format(date);

        String photo_path = Paths.get(ocr_upload_path,dataStr+"-ocr.jpg").toString();

        boolean bd1 = Utils.downloadRequestFile(file,photo_path,ocrReturnRes);

        if(!bd1)
        {
            return new ResponseEntity<>(ocrReturnRes, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        int ret = -1;

        int charlen = 34;

        Pointer pointer = new Memory(charlen);
        ret = JnaImports.CLibraryOcr.INSTANCE.ocr(dataStr+"-ocr.jpg",pointer,charlen);

        if(ret != 0){
            ocrReturnRes.setMessage("ocr failed");
            return new ResponseEntity<>(ocrReturnRes, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        //获取字节数组
        byte[] byteArray = pointer.getByteArray(0, charlen-1);

        ocrReturnRes.setChars(new String(byteArray));
        ocrReturnRes.setMessage("ok");
        ocrReturnRes.setStatus(Constant.successStr);
        return new ResponseEntity<>(ocrReturnRes, HttpStatus.OK);
    }
}
